package com.bringspring.system.message.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bringspring.common.util.StringUtils;
import com.bringspring.system.message.entity.SynThirdInfoEntity;
import com.bringspring.system.message.mapper.SynThirdInfoMapper;
import com.bringspring.system.message.model.message.SynThirdInfoCrForm;
import com.bringspring.system.message.service.SynThirdInfoService;
import com.bringspring.system.message.util.SynThirdConsts;
import com.bringspring.system.message.util.SynThirdTotal;
import com.bringspring.system.permission.entity.OrganizeEntity;
import com.bringspring.system.permission.service.OrganizeService;
import com.bringspring.system.permission.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.bringspring.system.external.constant.WxCpSysConfigConsts.TOP_SYS_PID;
import static com.bringspring.system.message.util.SynThirdConsts.DATA_TYPE_ORG;
import static com.bringspring.system.message.util.SynThirdConsts.DATA_TYPE_USER;

/**
 * 第三方工具的公司-部门-用户同步表模型
 *
 * @版本： V1.0.0
 * @版权： 股份有限公司
 * @作者： 开发平台组
 * @日期： 2021/4/23 17:33
 */
@Service
public class SynThirdInfoServiceImpl extends ServiceImpl<SynThirdInfoMapper, SynThirdInfoEntity> implements SynThirdInfoService {

    @Autowired
    private OrganizeService organizeServicel;
    @Autowired
    private UserService userService;

    @Override
    public List<SynThirdInfoEntity> getList(SynThirdInfoCrForm synThirdInfoCrForm) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(String.valueOf(synThirdInfoCrForm.getThirdtype()))){
            queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, synThirdInfoCrForm.getThirdtype()));
        }
        if(StringUtils.isNotEmpty(String.valueOf(synThirdInfoCrForm.getDatatype()))){
            queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, synThirdInfoCrForm.getDatatype()));
        }
        if(StringUtils.isNotEmpty(synThirdInfoCrForm.getSysObjId())){
            queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getSystemObjectId, synThirdInfoCrForm.getSysObjId()));
        }
        if(StringUtils.isNotEmpty(synThirdInfoCrForm.getThirdObjId())){
            queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdObjectId, synThirdInfoCrForm.getThirdObjId()));
        }
        if(StringUtils.isNotEmpty(String.valueOf(synThirdInfoCrForm.getSynstate()))){
            queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getSynState, synThirdInfoCrForm.getSynstate()));
        }
        queryWrapper.lambda().orderByDesc(SynThirdInfoEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<SynThirdInfoEntity> getList(String thirdType, String dataType) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, Integer.valueOf(thirdType)));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, Integer.valueOf(dataType)));
        queryWrapper.lambda().orderByDesc(SynThirdInfoEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<SynThirdInfoEntity> getListByCrop(String thirdType, String dataType, String crop) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, Integer.valueOf(thirdType)));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, Integer.valueOf(dataType)));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getCropId, crop));
        queryWrapper.lambda().orderByDesc(SynThirdInfoEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<SynThirdInfoEntity> getListByObjId(Integer thirdType, List<String> objId) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SynThirdInfoEntity::getThirdType, Integer.valueOf(thirdType)).in(SynThirdInfoEntity::getSystemObjectId, objId);
        return this.list(queryWrapper);
    }

    @Override
    public SynThirdInfoEntity getInfo(String id) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SynThirdInfoEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    public void create(SynThirdInfoEntity entity) {
        this.save(entity);
    }


    @Override
    public boolean update(String id, SynThirdInfoEntity entity) {
        entity.setId(id);
        return this.updateById(entity);
    }

    @Override
    public void delete(SynThirdInfoEntity entity) {
        if (entity != null) {
            this.removeById(entity.getId());
        }
    }

    @Override
    public SynThirdInfoEntity getInfoBySysObjId(String thirdType, String dataType, String id) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, thirdType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, dataType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getSystemObjectId, id));
        return this.getOne(queryWrapper);
    }

    @Override
    public List<SynThirdInfoEntity> getInfoBySysObjIds(String thirdType, String dataType, String id) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, thirdType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, dataType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getSystemObjectId, id));
        return this.list(queryWrapper);
    }

    @Override
    public SynThirdInfoEntity getInfoByThirdObjId(String thirdType, String dataType, String thirdObjid) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, thirdType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, dataType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdObjectId, thirdObjid));
        return this.getOne(queryWrapper);
    }

    @Override
    public SynThirdInfoEntity getInfoByThirdObjId(String thirdType, String dataType, String thirdObjid, String corpId) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getCropId, corpId));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, thirdType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, dataType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdObjectId, thirdObjid));
        return this.getOne(queryWrapper);
    }

    @Override
    public List<SynThirdInfoEntity> getInfoByThirdObjIds(String thirdType, String dataType, String thirdObjid) {
        QueryWrapper<SynThirdInfoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdType, thirdType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getDataType, dataType));
        queryWrapper.lambda().and(t -> t.eq(SynThirdInfoEntity::getThirdObjectId, thirdObjid));
        return this.list(queryWrapper);
    }

    @Override
    public SynThirdTotal getSynTotal(String thirdType, String dataType) {
        String synType = dataType.equals(DATA_TYPE_ORG) ? "组织" : "用户";
        Integer recordTotal = 0;
        Long synSuccessCount = 0L;
        Long synFailCount = 0L;
        Long unSynCount = 0L;
        Date synDate = null;

        // 获取列表数据
        List<SynThirdInfoEntity> synList = getList(thirdType, dataType);
        if (synList != null && synList.size() > 0) {
            synSuccessCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_OK)).count();
            synFailCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_FAIL)).count();
            unSynCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_NO)).count();
            synList = synList.stream().filter(x -> x.getLastModifyTime() != null).collect(Collectors.toList());
            if (synList.size() > 0) {
                Optional<SynThirdInfoEntity> max = synList.stream().max(Comparator.comparing(SynThirdInfoEntity::getLastModifyTime));
                synDate = max.get().getLastModifyTime();
            } else {
                synDate = null;
            }
        }

        // 获取本系统的组织、用户表的记录数
        if (dataType.equals(DATA_TYPE_ORG)) {
            // 获取组织(公司和部门)的记录数
            recordTotal = organizeServicel.getList().size();
        } else {
            // 获取用户的记录数
            recordTotal = userService.getList().size();
        }

        // 写入同步统计模型对象
        SynThirdTotal synThirdTotal = new SynThirdTotal();
        synThirdTotal.setSynType(synType);
        synThirdTotal.setRecordTotal(recordTotal);
        synThirdTotal.setSynSuccessCount(synSuccessCount);
        synThirdTotal.setSynFailCount(synFailCount);
        synThirdTotal.setUnSynCount(unSynCount);
        synThirdTotal.setSynDate(synDate);

        return synThirdTotal;
    }

    @Override
    public List<SynThirdTotal> getCorpSynTotal(String thirdType, String corpId) {
        List<SynThirdTotal> synTotalList = new ArrayList<>();

        // 部门同步情况，写入同步统计模型对象
        SynThirdTotal synThirdTotal = new SynThirdTotal();
        synThirdTotal.setSynType("组织");
        /**
         * 获取第三方同步信息部门列表数据
         */
        List<SynThirdInfoEntity> synList = countSynRestState(thirdType, DATA_TYPE_ORG, corpId, synThirdTotal);

        /**
         * 查询系统所有公司列表
         */
        String companyid = null;
        List<OrganizeEntity> allCompanyList = organizeServicel.getAllCompanyList(null);
        if (CollectionUtil.isNotEmpty(allCompanyList)) {
            for (OrganizeEntity dept : allCompanyList) {
                if (TOP_SYS_PID.equals(dept.getParentId()) ||"0".equals(dept.getParentId()) ) {
                    if (synList.stream().filter(t -> t.getSystemObjectId().equals(dept.getId())).count() > 0 ? true :
                            false) {
                        /**
                         * 匹配到顶级部门顶级公司ID
                         */
                        companyid = dept.getId();
                        break;
                    }
                }
            }
        }

        if (StringUtils.isNotEmpty(companyid)) {
            /**
             * 查询系统所有部门列表
             */
            List<OrganizeEntity> orgList = organizeServicel.getListLikeOrgIdTree(companyid);
            // 获取组织(公司和部门)的记录数
            synThirdTotal.setRecordTotal(orgList.size());
            synTotalList.add(synThirdTotal);

            // 用户同步情况，写入同步统计模型对象
            SynThirdTotal synThirdTotalU = new SynThirdTotal();
            synThirdTotalU.setSynType("用户");
            /**
             * 获取第三方同步信息用户列表数据
             */
            countSynRestState(thirdType, DATA_TYPE_USER, corpId, synThirdTotalU);

            List<String> orgIds = orgList.stream().map(OrganizeEntity::getId).collect(Collectors.toList());
            /**
             * 获取系统所有用户列表
             */
            synThirdTotalU.setRecordTotal(userService.getUserByOrgIds(orgIds).size());
            synTotalList.add(synThirdTotalU);
        }

        return synTotalList;
    }

    @Override
    public SynThirdTotal getCorpDataTypeSynTotal(String thirdType, String dataType, String corpId) {
        String synType = dataType.equals(DATA_TYPE_ORG) ? "组织" : "用户";
        // 同步情况，写入同步统计模型对象
        SynThirdTotal synThirdTotal = new SynThirdTotal();
        synThirdTotal.setSynType(synType);

        /**
         * 获取第三方同步信息部门列表数据
         */
        List<SynThirdInfoEntity> deptSynList;
        if (dataType.equals(DATA_TYPE_ORG)) {
            deptSynList = countSynRestState(thirdType, DATA_TYPE_ORG, corpId, synThirdTotal);
        } else {
            deptSynList = getListByCrop(thirdType, DATA_TYPE_ORG, corpId);
        }
        /**
         * 查询系统所有公司列表
         */
        String companyid = null;
        List<OrganizeEntity> allCompanyList = organizeServicel.getAllCompanyList(null);
        if (CollectionUtil.isNotEmpty(allCompanyList)) {
            for (OrganizeEntity dept : allCompanyList) {
                if (TOP_SYS_PID.equals(dept.getParentId())) {
                    if (deptSynList.stream().filter(t -> t.getSystemObjectId().equals(dept.getId())).count() > 0 ? true :
                            false) {
                        /**
                         * 匹配到顶级部门顶级公司ID
                         */
                        companyid = dept.getId();
                        break;
                    }
                }
            }
        }

        if (StringUtils.isNotEmpty(companyid)) {
            /**
             * 查询系统所有部门列表
             */
            List<OrganizeEntity> orgList = organizeServicel.getListLikeOrgIdTree(companyid);
            if (dataType.equals(DATA_TYPE_ORG)) {
                // 获取组织(公司和部门)的记录数
                synThirdTotal.setRecordTotal(orgList.size());
            } else {
                /**
                 * 获取第三方同步信息用户列表数据
                 */
                countSynRestState(thirdType, DATA_TYPE_USER, corpId, synThirdTotal);
                List<String> orgIds = orgList.stream().map(OrganizeEntity::getId).collect(Collectors.toList());
                /**
                 * 获取系统所有用户列表
                 */
                synThirdTotal.setRecordTotal(userService.getUserByOrgIds(orgIds).size());
            }
        }

        return synThirdTotal;
    }

    public List<SynThirdInfoEntity> countSynRestState(String thirdType, String dataType, String corpId,
                                                      SynThirdTotal synThirdTotal){
        Long synSuccessCount = 0L;
        Long synFailCount = 0L;
        Long unSynCount = 0L;
        Date synDate = null;
        // 获取用户列表数据
        List<SynThirdInfoEntity> synList = getListByCrop(thirdType, dataType, corpId);
        if (synList != null && synList.size() > 0) {
            synSuccessCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_OK)).count();
            synFailCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_FAIL)).count();
            unSynCount = synList.stream().filter(t -> t.getSynState().equals(SynThirdConsts.SYN_STATE_NO)).count();
            synList = synList.stream().filter(x -> x.getLastModifyTime() != null).collect(Collectors.toList());
            if (synList.size() > 0) {
                Optional<SynThirdInfoEntity> max =
                        synList.stream().max(Comparator.comparing(SynThirdInfoEntity::getLastModifyTime));
                synDate = max.get().getLastModifyTime();
            } else {
                synDate = null;
            }
        }
        synThirdTotal.setSynSuccessCount(synSuccessCount);
        synThirdTotal.setSynFailCount(synFailCount);
        synThirdTotal.setUnSynCount(unSynCount);
        synThirdTotal.setSynDate(synDate);
        return synList;
    }
}
